/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.tukano.swingdeco.containers;

import com.kitfox.svg.*;
import java.awt.*;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;

/**
 *
 * @author utente4
 */
public class JSVGContainer extends JPanel {
    
    public static class SvgLayout implements LayoutManager {
        
        private final Map<Component, String> components = new LinkedHashMap<Component, String>();
        private final SVGDiagram diagram;

        public SvgLayout(String res) {
            URI uri = SVGCache.getSVGUniverse().loadSVG(SvgLayout.class.getResource(res));
            diagram = SVGCache.getSVGUniverse().getDiagram(uri);
        }
        
        public Component get(String name) {
            for (Map.Entry<Component, String> entry : components.entrySet()) {
                if(entry.getValue().equals(name)) return entry.getKey();
            }
            return null;
        }

        public void addLayoutComponent(String name, Component comp) {
            components.put(comp, name);
        }

        public void removeLayoutComponent(Component comp) {
            components.remove(comp);
        }

        public Dimension preferredLayoutSize(Container parent) {
            return minimumLayoutSize(parent);
        }

        public Dimension minimumLayoutSize(Container parent) {
            synchronized (parent.getTreeLock()) {
                Dimension size = new Dimension();
                Insets insets = parent.getInsets();
                for (String key : components.values()) {
                    SVGElement element = diagram.getElement(key);
                    if(element instanceof RenderableElement) {
                        RenderableElement re = (RenderableElement) element;
                        try {
                            Rectangle bounds = re.getBoundingBox().getBounds();
                            size.width = Math.max(size.width, bounds.x + bounds.width);
                            size.height = Math.max(size.height, bounds.y+bounds.height);
                        } catch (SVGException ex) {
                            Logger.getLogger(JSVGContainer.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
                size.width += insets.left + insets.right;
                size.height += insets.top + insets.bottom;
                return size;
            }
        }

        public void layoutContainer(Container parent) {
            synchronized (parent.getTreeLock()) {
                for (Component component : parent.getComponents()) {
                    Insets insets = parent.getInsets();
                    String key = components.get(component);
                    if(key != null) {
                        SVGElement element = diagram.getElement(key);
                        if(element instanceof RenderableElement) {
                            RenderableElement re = (RenderableElement) element;
                            try {
                                Rectangle bounds = re.getBoundingBox().getBounds();
                                component.setBounds(insets.left+bounds.x, insets.top+bounds.y, bounds.width, bounds.height);
                            } catch (SVGException ex) {
                                Logger.getLogger(JSVGContainer.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                }
            }
        }
    
}
    
    //Default serial version code
    private static final long serialVersionUID = 0;

    public JSVGContainer(String svgLayoutResource) {
        super(new SvgLayout(svgLayoutResource));
    }
    
    public JTextComponent getTextComponent(String name) {
        return get(name, JTextComponent.class);
    }
    
    public AbstractButton getButton(String name) {
        return get(name, AbstractButton.class);
    }
    
    public JList getList(String name) {
        return get(name, JList.class);
    }
    
    public <T extends Component> T get(String name, Class<T> type) {
        LayoutManager layout = getLayout();
        if(layout instanceof SvgLayout) {
            SvgLayout svgLayout = (SvgLayout) layout;
            Component component = svgLayout.get(name);
            if(component != null && type.isAssignableFrom(component.getClass())) {
                return type.cast(component);
            } else {
                return null;
            }
        } else {
            return null;
        }
    }
}
